package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusBpmnInfo;
import cn.wolfcode.business.domain.BusCarPackageAudit;
import cn.wolfcode.business.domain.BusServiceItem;
import cn.wolfcode.business.mapper.BusServiceItemMapper;
import cn.wolfcode.business.service.IBusBpmnInfoService;
import cn.wolfcode.business.service.IBusCarPackageAuditService;
import cn.wolfcode.business.service.IBusServiceItemService;
import cn.wolfcode.business.vo.AuditInfoVO;
import cn.wolfcode.business.vo.CarPackageAuditVO;
import cn.wolfcode.common.core.domain.entity.SysUser;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.SecurityUtils;
import cn.wolfcode.system.service.ISysConfigService;
import cn.wolfcode.system.service.ISysUserService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务项Service业务层处理
 * 
 * @author wolfcode
 * @date 2025-04-29
 */
@Service
public class BusServiceItemServiceImpl implements IBusServiceItemService 
{
    @Autowired
    private BusServiceItemMapper busServiceItemMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IBusBpmnInfoService busBpmnInfoService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IBusCarPackageAuditService auditService;

    /**
     * 查询服务项
     * 
     * @param id 服务项主键
     * @return 服务项
     */
    @Override
    public BusServiceItem selectBusServiceItemById(Long id)
    {
        return busServiceItemMapper.selectBusServiceItemById(id);
    }

    /**
     * 查询服务项列表
     * 
     * @param busServiceItem 服务项
     * @return 服务项
     */
    @Override
    public List<BusServiceItem> selectBusServiceItemList(BusServiceItem busServiceItem)
    {
        return busServiceItemMapper.selectBusServiceItemList(busServiceItem);
    }

    /**
     * 新增服务项
     * 
     * @param busServiceItem 服务项
     * @return 结果
     */
    @Override
    public int insertBusServiceItem(BusServiceItem busServiceItem)
    {
        //  1. 参数合理化校验
        if (busServiceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 	2. 前台校验的后端都需要再校验一次（非空）
        if(busServiceItem.getName() == null || busServiceItem.getOriginalPrice() == null||
        busServiceItem.getDiscountPrice() == null || busServiceItem.getCarPackage() == null ||
        busServiceItem.getServiceCatalog() == null){
            throw new RuntimeException("非法参数");
        }
        // 	3. 价格合理化校验（折扣价需要 >=0 且 <= 原价。）
        // BigDecimal 中比较方法为 compaerTo
        // 若一致则返回 0   调用者（前面）大返回正数    参数（后面）大返回复数
        if(!(busServiceItem.getDiscountPrice().compareTo(new BigDecimal("0")) >= 0 &&
            busServiceItem.getOriginalPrice().compareTo(new BigDecimal("0")) >= 0 &&
            busServiceItem.getDiscountPrice().compareTo(busServiceItem.getOriginalPrice()) <= 0)){
            throw new RuntimeException("价格必须大于0，且折扣价必须小于原价");
        }
        // 	4. 是否套餐
        if(BusServiceItem.CARPACKAGE_NO.equals(busServiceItem.getCarPackage())){
            //      - 非套餐，状态需要设置为 -->  无需审核4
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_NO_REQUIRED);
        } else {
            //      - 是套餐，状态需要设置为 -->  初始化0
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_INIT);
        }
        // 	5. 安全性考虑。需要将状态设置为下架。
        busServiceItem.setSaleStatus(BusServiceItem.SALESTATUS_OFF);
        busServiceItem.setCreateTime(DateUtils.getNowDate());
        return busServiceItemMapper.insertBusServiceItem(busServiceItem);
    }

    /**
     * 修改服务项
     * 
     * @param busServiceItem 服务项
     * @return 结果
     */
    @Override
    public int updateBusServiceItem(BusServiceItem busServiceItem)
    {
        //  1. 参数合理化校验
        if (busServiceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 	2. 前台校验的后端都需要再校验一次（非空）
        if(busServiceItem.getName() == null || busServiceItem.getOriginalPrice() == null||
                busServiceItem.getDiscountPrice() == null || busServiceItem.getCarPackage() == null ||
                busServiceItem.getServiceCatalog() == null){
            throw new RuntimeException("非法参数");
        }
        // 	3. 价格合理化校验（折扣价需要 >=0 且 <= 原价。）
        if(!(busServiceItem.getDiscountPrice().compareTo(new BigDecimal("0")) >= 0 &&
                busServiceItem.getOriginalPrice().compareTo(new BigDecimal("0")) >= 0 &&
                busServiceItem.getDiscountPrice().compareTo(busServiceItem.getOriginalPrice()) <= 0)){
            throw new RuntimeException("价格必须大于0，且折扣价必须小于原价");
        }
        // 4. 是否套餐不能更改。
        BusServiceItem oldObj = this.selectBusServiceItemById(busServiceItem.getId());
        if(oldObj == null){
            throw new RuntimeException("非法参数");
        }
        // 修改的商品名称不能重复
        int count = busServiceItemMapper.selectCountByName(busServiceItem.getName());
        if(!(busServiceItem.getName().equalsIgnoreCase(oldObj.getName())) && count > 0){
            throw new RuntimeException("修改的服务项名称已重复，请重新修改");
        }
        if(!oldObj.getCarPackage().equals(busServiceItem.getCarPackage())){
            throw new RuntimeException("是否套餐不能修改");
        }
        // 5. 必须是下架状态
        if(BusServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())){
            throw new RuntimeException("上架中的服务项禁止修改");
        }
        //   - 不是套餐可以直接修改。
        //   - 若是套餐：
        //     - 审核中不能修改
        //     - 初始可以直接修改
        //     - 审核通过/审核拒绝可以修改，但是修改后需要将状态重置为初始化。
        if(BusServiceItem.CARPACKAGE_YES.equals(oldObj.getCarPackage()) &&
                BusServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())){
            throw new RuntimeException("审核中的服务项禁止修改");
        }
        if(BusServiceItem.CARPACKAGE_YES.equals(oldObj.getCarPackage()) &&
                (BusServiceItem.AUDITSTATUS_APPROVED.equals(oldObj.getAuditStatus()) ||
                BusServiceItem.AUDITSTATUS_REPLY.equals(oldObj.getAuditStatus()))){
            //     - 审核通过/审核拒绝可以修改，但是修改后需要将状态重置为初始化。
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_INIT);
        }
        // 6. 安全性考虑。需要将状态设置为下架。
        busServiceItem.setSaleStatus(BusServiceItem.SALESTATUS_OFF);
        return busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }

    /**
     * 批量删除服务项
     * 
     * @param ids 需要删除的服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemByIds(Long[] ids)
    {
        //  1. 参数合理化校验
        if(!(ids != null && ids.length > 0)){
            throw new RuntimeException("非法参数");
        }
        // 由于当前这个页面没有批量删除
        Long id = ids[0];
        BusServiceItem serviceItem = this.selectBusServiceItemById(id);
        if (serviceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 	2. 必须是下架状态（上架中的商品不能删除）
        if(BusServiceItem.SALESTATUS_ON.equals(serviceItem.getSaleStatus())){
            throw new RuntimeException("上架中的商品禁止删除");
        }
        // 	3. 下架状态且是套餐且是审批中不能删除
        if(BusServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
            && BusServiceItem.AUDITSTATUS_AUDITING.equals(serviceItem.getAuditStatus())){
            throw new RuntimeException("审核中的商品禁止删除");
        }
        return busServiceItemMapper.deleteBusServiceItemByIds(ids);
    }

    /**
     * 删除服务项信息
     * 
     * @param id 服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemById(Long id)
    {
        return busServiceItemMapper.deleteBusServiceItemById(id);
    }

    /**
     * 上架功能
     * @param id
     * @return
     */
    @Override
    public int saleOn(Long id) {
        //  1. 参数合理化校验
        if(id == null){
            throw new RuntimeException("非法参数");
        }
        BusServiceItem busServiceItem = this.selectBusServiceItemById(id);
        if (busServiceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 	2. 必须是下架的商品才可以进行上架操作。
        if(BusServiceItem.SALESTATUS_ON.equals(busServiceItem.getSaleStatus())){
            throw new RuntimeException("该服务项已经上架");
        }
        // 	3. 如果是套餐且状态为审批通过，才可以上架。
        if(BusServiceItem.CARPACKAGE_YES.equals(busServiceItem.getCarPackage()) && // 是套餐
            !BusServiceItem.AUDITSTATUS_APPROVED.equals(busServiceItem.getAuditStatus())){// 状态不是审批通过
            throw new RuntimeException("该服务项必须审批通过后才可以进行上架操作");
        }
        // 	5. 将状态修改为上架
        return busServiceItemMapper.changeSaleStatusById(id,BusServiceItem.SALESTATUS_ON);
    }

    @Override
    public int saleOff(Long id) {
        //  1. 参数合理化校验
        if(id == null){
            throw new RuntimeException("非法参数");
        }
        BusServiceItem busServiceItem = this.selectBusServiceItemById(id);
        if (busServiceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 	2. 必须是下架的商品才可以进行上架操作。
        if(BusServiceItem.SALESTATUS_OFF.equals(busServiceItem.getSaleStatus())){
            throw new RuntimeException("该服务项已经下架");
        }
        return busServiceItemMapper.changeSaleStatusById(id,BusServiceItem.SALESTATUS_OFF);
    }

    /**
     * 发起审核对话框数据回显
     */
    @Override
    public AuditInfoVO getAuditInfo(Long id) {
        // 参数合理化验证
        if(id == null){
            throw new RuntimeException("非法参数");
        }
        BusServiceItem serviceItem = this.selectBusServiceItemById(id);
        if(serviceItem == null){
            throw new RuntimeException("非法参数");
        }
        // 创建 VO 对象，封装数据
        AuditInfoVO vo = new AuditInfoVO();
        // 准备服务项内容
        vo.setBusServiceItem(serviceItem);
        // 准备店长集合
        List<SysUser> shopOwnerList = sysUserService.selectUserByRoleKey("shopOwner");
        vo.setShopOwnerList(shopOwnerList);
        // 准备阈值
        String discountPricesLimit = sysConfigService.selectConfigByKey("discountPriceLimit");
        vo.setDiscountPriceLimit(new BigDecimal(discountPricesLimit));
        if(serviceItem.getDiscountPrice().compareTo(new BigDecimal(discountPricesLimit)) >= 0){
            // 准备财务集合
            List<SysUser> financesList = sysUserService.selectUserByRoleKey("finance");
            vo.setFinancesList(financesList);
        }
        return vo;
    }

    /**
     * 审批功能
     */
    @Override
    @Transactional
    public int startAudit(CarPackageAuditVO vo) {
        // 参数合理化校验
        if(vo == null){
            throw new RuntimeException("非法参数");
        }
        if(vo.getBusServiceItemId() == null || vo.getShopOwnerId() == null){
            throw new RuntimeException("非法参数");
        }
        // 根据服务项 id 查询服务项具体信息
        BusServiceItem serviceItem = this.selectBusServiceItemById(vo.getBusServiceItemId());
        if (serviceItem == null) {
            throw new RuntimeException("非法参数");
        }
        String discountPricesLimit = sysConfigService.selectConfigByKey("discountPriceLimit");
        if(serviceItem.getDiscountPrice().compareTo(new BigDecimal(discountPricesLimit)) >= 0 && vo.getFinanceId() == null){
            throw new RuntimeException("非法参数");
        }
        // 必须是套餐
        if(BusServiceItem.CARPACKAGE_NO.equals(serviceItem.getCarPackage())){
            throw new RuntimeException("非套餐禁止发起审核");
        }
        // 必须是下架状态
        if(BusServiceItem.SALESTATUS_ON.equals(serviceItem.getSaleStatus())){
            throw new RuntimeException("已上架的服务项禁止发起审核");
        }
        // 必须是初始化状态
        if(!(BusServiceItem.AUDITSTATUS_INIT.equals(serviceItem.getAuditStatus()))){
            throw new RuntimeException("状态必须是初始化才可以发起审核");
        }
        // 准备快照表数据
        BusCarPackageAudit audit = new BusCarPackageAudit();
        audit.setServiceItemId(serviceItem.getId());
        audit.setServiceItemName(serviceItem.getName());
        audit.setServiceItemInfo(serviceItem.getInfo());
        audit.setServiceItemPrice(serviceItem.getDiscountPrice());
        // audit.setInstanceId();   必须要发起流程实例后才可以添加
        audit.setCreatorId(SecurityUtils.getUserId().toString());
        audit.setInfo(vo.getInfo());
        audit.setStatus(BusCarPackageAudit.STATUS_IN_PROGRESS);
        audit.setCreateTime(new Date());
        // 向快照表中插入数据 （carPackageAudit）
        auditService.insertBusCarPackageAudit(audit);
        // 启动流程实例  根据我们特定的值 --> BpmnInfo 对象  -->  就可以找到套餐的 Key + version
        BusBpmnInfo busBpmnInfo = busBpmnInfoService.selectByTypeId(BusCarPackageAudit.FLOW_AUDIT_TYPE);
        String processDeinitionKey = busBpmnInfo.getProcessDefinitionKey();
        // 设置流程变量参数
        Map<String,Object> map = new HashMap<>();
        map.put("shopOwnerId",vo.getShopOwnerId());
        if(vo.getFinanceId() != null){
            map.put("financeId",vo.getFinanceId());
        }
        // 启动流程实例
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey(processDeinitionKey, audit.getId().toString(), map);
        // 获取启动流程实例后获取的流程实例 id
        String processInstanceId = processInstance.getProcessInstanceId();
        // 对快照表进行 instanceId 更新。这里可以使用全量更新。因为这个对象是我们自己再后端创建的，不会存在危险数据。
        audit.setInstanceId(processInstanceId);
        auditService.updateBusCarPackageAudit(audit);
        // 更新业务表状态（服务项表 serviceItem）
        return busServiceItemMapper.changeAuditStatus(vo.getBusServiceItemId(),BusServiceItem.AUDITSTATUS_AUDITING);
    }

    /**
     * 根据 id 修改审核状态
     */
    @Override
    public int changeAuditStatusById(Long id, Integer status) {
        return busServiceItemMapper.changeAuditStatus(id,status);
    }
}
